package com.google.code.bankagregator.vo;

import com.google.code.bankagregator.entities.*;

/**
 * Class for display list of offers<br/>
 * with additional credit information<br/>
 * <ul>
 * <li>credit overpayment</li>
 * <li>amount of down payment, if exist</li>
 * </ul>
 * <br/>
 * Additional information based and calculated on<br/>
 * user criteria and conditions of a particular credit.<br/>
 * User: kaiser
 */
public class CreditOffer implements Comparable<CreditOffer> {


    public final int DAY_IN_MONTH = 31;
    public final int DAY_IN_YEAR = 365;


    /**
     * Credit entity
     */
    private Credit credit;

    /**
     * Credit down payment if exist
     */
    private Double downPayment = 0.0;

    /**
     * total overpayment under the terms of the credit
     */
    private Double overpayment = 0.0;


    public CreditOffer(Credit credit, Credit criteria) {
        setCredit(credit);
        calculateDownPayment(criteria);
        calculateOverpayment(criteria);
    }

    /**
     * Calculate credit overpayment<br/>
     * it is based on user criteria<br/>
     * <ul>
     * <li>credit term</li>
     * <li>amount required on credit</li>
     * <li>conditions of a particular credit</li>
     * </ul>
     *
     * @param criteria User request for search credit list
     */
    private void calculateOverpayment(Credit criteria) {
        int creditSize = criteria.getMaxAmount();
        Double percentForPeriod = ((criteria.getTerm() * DAY_IN_MONTH) / DAY_IN_YEAR) * (getCreditRate() / 100);

        Double creditBody = criteria.getMaxAmount() - getDownPayment();

        this.overpayment = creditBody * percentForPeriod;
    }

    /**
     * Calculate credit overpayment<br/>
     * it is based on user criteria<br/>
     * <ul>
     * <li>amount required on credit</li>
     * <li>prepayment condition of a particular credit</li>
     * </ul>
     *
     * @param criteria User request for search credit list
     */
    private void calculateDownPayment(Credit criteria) {
        if (isPrepayment()) {
            int creditSize = criteria.getMaxAmount();
            this.downPayment = creditSize * getPrepayment() / 100;
        }
    }


    public String getName() {
        return getCredit().getName();
    }

    public Currency getCurrency() {
        return getCredit().getCurrency();
    }

    public Bank getBank() {
        return getCredit().getBank();
    }

    public String getUrl() {
        return getCredit().getUrl();
    }

    public State getState() {
        return getCredit().getState();
    }

    public Double getDownPayment() {
        return downPayment;
    }

    public Double getOverpayment() {
        return overpayment;
    }

    public double getCreditRate() {
        return getCredit().getCreditRate();
    }

    public int getMaxAmount() {
        return getCredit().getMaxAmount();
    }

    public int getMinAmount() {
        return getCredit().getMinAmount();
    }

    public int getTerm() {
        return getCredit().getTerm();
    }

    public int getTermInMonth() {
        Integer term = getCredit().getTerm();
        return (Integer) term /DAY_IN_MONTH;
    }

    public CreditType getType() {
        return getCredit().getType();
    }


    public Double getPrepayment() {
        return credit.getPrepayment();
    }

    private void setCredit(Credit credit) {
        this.credit = credit;
    }

    public Credit getCredit() {
        return credit;
    }

    @Override
    public int compareTo(CreditOffer o) {
        return Double.compare(getOverpayment(), o.getOverpayment());
    }

    /**
     * Check is prepayment value exist in credit condition
     *
     * @return true if exist
     */
    private boolean isPrepayment() {
        return Double.compare(getPrepayment(), 0.0) == 1;
    }
}
